<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SSML Editor</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#165DFF',
                        secondary: '#36CFC9',
                        neutral: '#F2F3F5',
                        dark: '#1D2129',
                    },
                    fontFamily: {
                        inter: ['Inter', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .editor-shadow {
                box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
            }
            .toolbar-btn {
                @apply p-2 rounded hover:bg-neutral transition-all duration-200;
            }
            .toolbar-btn.active {
                @apply bg-primary/10 text-primary;
            }
        }
    </style>
</head>

<body class="font-inter bg-gray-50 text-dark min-h-screen flex flex-col">
    <!-- Header -->
    <header class="bg-white border-b border-gray-200 sticky top-0 z-50">
        <div class="container mx-auto px-4 py-3 flex items-center justify-between">
            <div class="flex items-center space-x-2">
                <i class="fa fa-code text-primary text-xl"></i>
                <h1 class="text-xl font-bold text-dark">SSML Editor</h1>
            </div>
            <div class="flex items-center space-x-4">
                <button id="save-btn"
                    class="flex items-center space-x-1 px-3 py-1.5 rounded-md bg-primary text-white hover:bg-primary/90 transition-all duration-200">
                    <i class="fa fa-save"></i>
                    <span>Save</span>
                </button>
                <button id="export-btn"
                    class="flex items-center space-x-1 px-3 py-1.5 rounded-md bg-white border border-gray-300 hover:bg-gray-50 transition-all duration-200">
                    <i class="fa fa-download"></i>
                    <span>Export</span>
                </button>
            </div>
        </div>
    </header>

    <!-- Main Content -->
    <main class="flex-1 container mx-auto px-4 py-6">
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
            <!-- SSML Editor -->
            <div class="bg-white rounded-xl editor-shadow p-4 flex flex-col h-full">
                <div class="mb-3 flex items-center justify-between">
                    <h2 class="text-lg font-semibold text-dark">SSML Code</h2>
                    <div class="flex items-center space-x-2">
                        <button id="validate-btn"
                            class="flex items-center space-x-1 px-2 py-1 rounded-md bg-secondary text-white hover:bg-secondary/90 transition-all duration-200">
                            <i class="fa fa-check"></i>
                            <span>Validate</span>
                        </button>
                    </div>
                </div>

                <!-- Toolbar -->
                <div class="bg-gray-50 p-2 rounded-lg mb-3 flex flex-wrap gap-1">
                    <button class="toolbar-btn" data-tag="speak" title="&lt;speak&gt;">
                        <i class="fa fa-volume-up"></i>
                    </button>
                    <button class="toolbar-btn" data-tag="prosody" title="&lt;prosody&gt;">
                        <i class="fa fa-sliders"></i>
                    </button>
                    <button class="toolbar-btn" data-tag="break" title="&lt;break&gt;">
                        <i class="fa fa-pause"></i>
                    </button>
                    <button class="toolbar-btn" data-tag="emphasis" title="&lt;emphasis&gt;">
                        <i class="fa fa-bold"></i>
                    </button>
                    <button class="toolbar-btn" data-tag="say-as" title="&lt;say-as&gt;">
                        <i class="fa fa-font"></i>
                    </button>
                    <button class="toolbar-btn" data-tag="audio" title="&lt;audio&gt;">
                        <i class="fa fa-music"></i>
                    </button>
                    <button class="toolbar-btn" data-tag="sub" title="&lt;sub&gt;">
                        <i class="fa fa-exchange"></i>
                    </button>
                    <button class="toolbar-btn" data-tag="p" title="&lt;p&gt;">
                        <i class="fa fa-paragraph"></i>
                    </button>
                    <button class="toolbar-btn" data-tag="s" title="&lt;s&gt;">
                        <i class="fa fa-sentence"></i>
                    </button>
                    <button class="toolbar-btn" data-tag="phoneme" title="&lt;phoneme&gt;">
                        <i class="fa fa-language"></i>
                    </button>
                </div>

                <!-- Code Editor -->
                <div class="flex-1 border border-gray-200 rounded-lg overflow-hidden">
                    <textarea id="ssml-code" class="w-full h-full p-4 font-mono text-sm focus:outline-none resize-none"
                        placeholder="Type your SSML code here...">&lt;speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US"&gt;
  &lt;p&gt;
    &lt;s&gt;Hello, welcome to the SSML Editor.&lt;/s&gt;
    &lt;s&gt;You can create and test your Speech Synthesis Markup Language here.&lt;/s&gt;
  &lt;/p&gt;
&lt;/speak&gt;</textarea>
                </div>
            </div>

            <!-- Preview -->
            <div class="bg-white rounded-xl editor-shadow p-4 flex flex-col h-full">
                <div class="mb-3 flex items-center justify-between">
                    <h2 class="text-lg font-semibold text-dark">Preview</h2>
                    <div class="flex items-center space-x-2">
                        <select id="voice-select"
                            class="border border-gray-300 rounded-md px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary">
                            <option value="en-US-Wavenet-D">English (US) - Wavenet D</option>
                            <option value="en-US-Wavenet-C">English (US) - Wavenet C</option>
                            <option value="en-GB-Wavenet-A">English (UK) - Wavenet A</option>
                            <option value="fr-FR-Wavenet-C">French - Wavenet C</option>
                            <option value="es-ES-Wavenet-B">Spanish - Wavenet B</option>
                        </select>
                        <button id="play-btn"
                            class="flex items-center space-x-1 px-3 py-1.5 rounded-md bg-primary text-white hover:bg-primary/90 transition-all duration-200">
                            <i class="fa fa-play"></i>
                            <span>Play</span>
                        </button>
                    </div>
                </div>

                <!-- Visual Preview -->
                <div
                    class="flex-1 border border-gray-200 rounded-lg overflow-hidden bg-gray-50 flex items-center justify-center">
                    <div id="preview-container" class="p-6 max-w-md">
                        <div id="preview-text" class="text-lg leading-relaxed">
                            Hello, welcome to the SSML Editor. You can create and test your Speech Synthesis Markup
                            Language here.
                        </div>
                    </div>
                </div>

                <!-- Audio Controls -->
                <div class="mt-3 border-t border-gray-200 pt-3">
                    <div class="flex items-center space-x-4">
                        <button id="stop-btn" class="text-gray-500 hover:text-primary transition-colors duration-200">
                            <i class="fa fa-stop text-lg"></i>
                        </button>
                        <button id="pause-btn" class="text-gray-500 hover:text-primary transition-colors duration-200">
                            <i class="fa fa-pause text-lg"></i>
                        </button>
                        <div class="flex-1">
                            <input type="range" id="volume-slider" min="0" max="1" step="0.1" value="1"
                                class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary">
                        </div>
                        <div class="w-10 text-right">
                            <span id="volume-value">100%</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </main>

    <!-- Footer -->
    <footer class="bg-white border-t border-gray-200 py-4 mt-6">
        <div class="container mx-auto px-4 text-center text-gray-500 text-sm">
            <p>SSML Editor | Created with <i class="fa fa-heart text-red-500"></i> for better speech experiences</p>
        </div>
    </footer>

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            // DOM Elements
            const ssmlCode = document.getElementById('ssml-code');
            const previewText = document.getElementById('preview-text');
            const playBtn = document.getElementById('play-btn');
            const stopBtn = document.getElementById('stop-btn');
            const pauseBtn = document.getElementById('pause-btn');
            const volumeSlider = document.getElementById('volume-slider');
            const volumeValue = document.getElementById('volume-value');
            const validateBtn = document.getElementById('validate-btn');
            const saveBtn = document.getElementById('save-btn');
            const exportBtn = document.getElementById('export-btn');
            const voiceSelect = document.getElementById('voice-select');
            const toolbarBtns = document.querySelectorAll('.toolbar-btn');

            // Audio synthesis variables
            let synth = window.speechSynthesis;
            let utterance = null;
            let isPlaying = false;

            // Initialize volume display
            volumeValue.textContent = `${Math.round(volumeSlider.value * 100)}%`;

            // Insert SSML tags from toolbar
            toolbarBtns.forEach(btn => {
                btn.addEventListener('click', function () {
                    const tag = this.getAttribute('data-tag');
                    insertTag(tag);
                    this.classList.add('active');
                    setTimeout(() => this.classList.remove('active'), 300);
                });
            });

            // Insert SSML tag at cursor position
            function insertTag(tag) {
                const textarea = ssmlCode;
                const start = textarea.selectionStart;
                const end = textarea.selectionEnd;
                const selectedText = textarea.value.substring(start, end);

                let tagContent = '';
                let placeholder = '';

                switch (tag) {
                    case 'speak':
                        tagContent = `<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">${selectedText || '<add your text here>'}</speak>`;
                        break;
                    case 'prosody':
                        placeholder = selectedText || 'text';
                        tagContent = `<prosody rate="medium" pitch="medium" volume="medium">${placeholder}</prosody>`;
                        break;
                    case 'break':
                        tagContent = '<break time="200ms"/>';
                        break;
                    case 'emphasis':
                        placeholder = selectedText || 'important text';
                        tagContent = `<emphasis level="moderate">${placeholder}</emphasis>`;
                        break;
                    case 'say-as':
                        placeholder = selectedText || '12345';
                        tagContent = `<say-as interpret-as="cardinal">${placeholder}</say-as>`;
                        break;
                    case 'audio':
                        tagContent = '<audio src="https://example.com/sound.mp3">audio description</audio>';
                        break;
                    case 'sub':
                        placeholder = selectedText || 'ASAP';
                        tagContent = `<sub alias="as soon as possible">${placeholder}</sub>`;
                        break;
                    case 'p':
                        placeholder = selectedText || 'paragraph text';
                        tagContent = `<p>${placeholder}</p>`;
                        break;
                    case 's':
                        placeholder = selectedText || 'sentence';
                        tagContent = `<s>${placeholder}</s>`;
                        break;
                    case 'phoneme':
                        placeholder = selectedText || 'word';
                        tagContent = `<phoneme alphabet="ipa" ph="wɜːd">${placeholder}</phoneme>`;
                        break;
                    default:
                        tagContent = `<${tag}>${selectedText || 'text'}</${tag}>`;
                }

                textarea.value = textarea.value.substring(0, start) + tagContent + textarea.value.substring(end);
                textarea.focus();

                // Place cursor inside the new tag if applicable
                if (tagContent.includes('add your text here')) {
                    const pos = start + tagContent.indexOf('<add your text here>');
                    textarea.selectionStart = pos;
                    textarea.selectionEnd = pos + '<add your text here>'.length;
                }
            }

            // Update preview text
            function updatePreview() {
                try {
                    const parser = new DOMParser();
                    const xmlDoc = parser.parseFromString(ssmlCode.value, "text/xml");

                    // Extract text content from SSML
                    let text = '';
                    const speakNode = xmlDoc.querySelector('speak');

                    if (speakNode) {
                        // Remove script nodes if present
                        const scriptNodes = xmlDoc.querySelectorAll('script');
                        scriptNodes.forEach(node => node.remove());

                        text = speakNode.textContent.trim();
                    } else {
                        text = xmlDoc.documentElement.textContent.trim();
                    }

                    previewText.textContent = text || 'No text to preview';

                    // Add visual indicators for SSML elements
                    previewText.innerHTML = text
                        .replace(/<break\s+time="(\d+)ms"\/>/gi, '<span class="inline-block mx-1 text-gray-400">⏸️</span>')
                        .replace(/<emphasis\s+level="(\w+)"[^>]*>(.*?)<\/emphasis>/gi, '<span class="font-bold text-primary">$2</span>')
                        .replace(/<prosody\s+rate="slow"[^>]*>(.*?)<\/prosody>/gi, '<span class="italic text-secondary">$1</span>');

                    return true;
                } catch (e) {
                    previewText.innerHTML = '<span class="text-red-500">Invalid SSML: ' + e.message + '</span>';
                    return false;
                }
            }

            // Validate SSML
            validateBtn.addEventListener('click', function () {
                const isValid = updatePreview();
                if (isValid) {
                    showNotification('SSML is valid!', 'success');
                } else {
                    showNotification('SSML validation failed! Check for errors.', 'error');
                }
            });

            // Play SSML
            playBtn.addEventListener('click', function () {
                if (isPlaying) {
                    synth.resume();
                    return;
                }

                if (synth.speaking) {
                    synth.cancel();
                }

                const isValid = updatePreview();
                if (!isValid) {
                    showNotification('Cannot play invalid SSML!', 'error');
                    return;
                }

                utterance = new SpeechSynthesisUtterance(previewText.textContent);
                utterance.volume = parseFloat(volumeSlider.value);

                // Set selected voice
                const selectedVoice = voiceSelect.value;
                const voices = synth.getVoices();
                const voice = voices.find(v => v.name === selectedVoice);

                if (voice) {
                    utterance.voice = voice;
                }

                utterance.onstart = function () {
                    isPlaying = true;
                    playBtn.innerHTML = '<i class="fa fa-pause"></i><span>Pause</span>';
                    showNotification('Playing audio...', 'info');
                };

                utterance.onend = function () {
                    isPlaying = false;
                    playBtn.innerHTML = '<i class="fa fa-play"></i><span>Play</span>';
                    showNotification('Audio finished playing.', 'info');
                };

                utterance.onerror = function (e) {
                    isPlaying = false;
                    playBtn.innerHTML = '<i class="fa fa-play"></i><span>Play</span>';
                    showNotification('Error: ' + e.error, 'error');
                };

                synth.speak(utterance);
            });

            // Stop audio
            stopBtn.addEventListener('click', function () {
                if (synth.speaking) {
                    synth.cancel();
                    isPlaying = false;
                    playBtn.innerHTML = '<i class="fa fa-play"></i><span>Play</span>';
                    showNotification('Audio stopped.', 'info');
                }
            });

            // Pause audio
            pauseBtn.addEventListener('click', function () {
                if (synth.speaking && !synth.paused) {
                    synth.pause();
                    isPlaying = false;
                    playBtn.innerHTML = '<i class="fa fa-play"></i><span>Play</span>';
                    showNotification('Audio paused.', 'info');
                }
            });

            // Volume control
            volumeSlider.addEventListener('input', function () {
                volumeValue.textContent = `${Math.round(this.value * 100)}%`;
                if (utterance) {
                    utterance.volume = parseFloat(this.value);
                }
            });

            // Save SSML
            saveBtn.addEventListener('click', function () {
                localStorage.setItem('ssml-code', ssmlCode.value);
                showNotification('SSML saved locally!', 'success');
            });

            // Export SSML
            exportBtn.addEventListener('click', function () {
                const blob = new Blob([ssmlCode.value], { type: 'text/xml' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = 'ssml_document.xml';
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                URL.revokeObjectURL(url);
            });

            // Load saved SSML on startup
            const savedSSML = localStorage.getItem('ssml-code');
            if (savedSSML) {
                ssmlCode.value = savedSSML;
                updatePreview();
            }

            // Update preview on text change
            ssmlCode.addEventListener('input', updatePreview);

            // Initialize voices
            function loadVoices() {
                const voices = synth.getVoices();
                voiceSelect.innerHTML = '';

                voices.forEach(voice => {
                    if (voice.lang.startsWith('en')) {
                        const option = document.createElement('option');
                        option.value = voice.name;
                        option.textContent = `${voice.name} (${voice.lang}) ${voice.default ? '- Default' : ''}`;
                        voiceSelect.appendChild(option);
                    }
                });
            }

            // Chrome needs a timeout
            setTimeout(loadVoices, 1000);

            // Safari and Firefox
            if (synth.onvoiceschanged !== undefined) {
                synth.onvoiceschanged = loadVoices;
            }

            // Show notification
            function showNotification(message, type = 'info') {
                // Create notification element
                const notification = document.createElement('div');
                notification.className = `fixed bottom-4 right-4 px-4 py-2 rounded-md shadow-lg transform transition-all duration-300 opacity-0 translate-y-4 z-50`;

                // Set notification type
                if (type === 'success') {
                    notification.classList.add('bg-green-50', 'text-green-800', 'border-l-4', 'border-green-400');
                } else if (type === 'error') {
                    notification.classList.add('bg-red-50', 'text-red-800', 'border-l-4', 'border-red-400');
                } else {
                    notification.classList.add('bg-blue-50', 'text-blue-800', 'border-l-4', 'border-blue-400');
                }

                // Add icon and message
                let icon = '';
                if (type === 'success') icon = '<i class="fa fa-check-circle mr-2"></i>';
                else if (type === 'error') icon = '<i class="fa fa-exclamation-circle mr-2"></i>';
                else icon = '<i class="fa fa-info-circle mr-2"></i>';

                notification.innerHTML = `${icon}${message}`;

                // Add to document
                document.body.appendChild(notification);

                // Animate in
                setTimeout(() => {
                    notification.classList.remove('opacity-0', 'translate-y-4');
                }, 10);

                // Remove after 3 seconds
                setTimeout(() => {
                    notification.classList.add('opacity-0', 'translate-y-4');
                    setTimeout(() => {
                        document.body.removeChild(notification);
                    }, 300);
                }, 3000);
            }
        });
    </script>
</body>

</html>